from flask import Blueprint
from flask import request
from flask import render_template
from flask import flash

from flask import session
from flask import redirect
from flask import url_for

from werkzeug import check_password_hash
from werkzeug import generate_password_hash

from app import db

from app.security import permission
from app.security import g

from app.models.usuario import Usuario
from app.models.proyecto import Proyecto

from app.wtforms.acceso_forms import LoginForm
from app.wtforms.acceso_forms import IngresarUsuarioForm
from app.wtforms.acceso_forms import CambiarContrasenhaForm
from app.wtforms.acceso_forms import ElegirProyectoForm


mod = Blueprint('acceso', __name__ , url_prefix='/acceso')


@mod.route('/sap/')
@permission
def home():
    """
    Manda al usuario que ongreso a la pagina principal del sistema
    """
    return render_template("/base.html", g=g)


@mod.route('/proyecto/<usuario>/<aux>/', methods=['GET', 'POST'])
def elegir_proyecto(usuario, aux):
    """
    Crea el formulario para la eleccion de proyectos y redirige a la pagina, recibe las
    peticiones get y post, valida el datto seleccionado para mandarlo a la pagina principal
    @param usuario: nombre del usuario que se logueo
    @param aux: id que identifica que template se debe utilizar para mostrar los datos, esta
    funcion es llamada por login y por cambiar_proyecto
    """
    
    
    # Obtenermos el usuario que se logueo
    user = Usuario.query.filter_by(nombre=usuario).first()
    session['usuario_id'] = user.id
    
    # Obtenemos todos los proyectos de la base de datos
    proyectos = Proyecto.query.all()
    
    # Hacemos una lista de todos los proyectos en donde el usuario sea miembro
    Lista_proyectos = []
    for proyecto in proyectos:
        if user in proyecto.miembros:
            Lista_proyectos.append((proyecto.id, proyecto.nombre))
            
    Lista_roles = []
    for rol in user.roles:
        Lista_roles.append(rol.nombre)
    
    if 'Administrador de Sistema' in Lista_roles:
        
        #flash('No puede ingresar al sistema, no es miembro de ningun proyecto')
        # Redirigimos a la pagina principal
        return redirect(url_for('acceso.home'))
        
    
    elif Lista_proyectos == []:
        return redirect(url_for('acceso.login'))       
        
    
    else:
        
        # Crea el formulario para la eleccion del proyecto entre los que el usuario es miembro
        form = ElegirProyectoForm(request.form)
    
        # Mostramos en pantalla esos proyectos 
        form.proyectos.choices = Lista_proyectos    
    
        # Validamos los datos ingresados en el formulario
        if form.validate_on_submit():
        
            # Creamos la session con el usuario y el proyecto seleccionado como atributos
           
            session['proyecto_id'] = form.proyectos.data
            p = session['proyecto_id']
             
            for proy in Lista_proyectos:
                if p[0] in proy:
                    nombre = proy[1]
            
            session['proyecto_nombre'] = nombre
                       
            # Redirigimos a la pagina principal
            return redirect(url_for('acceso.home'))
    if aux=='0':
        return render_template("acceso/elegir_proyecto.html", form=form)
    elif aux=='1':
        return render_template("acceso/cambiar_proyecto.html", form=form)


@mod.route('/login/', methods=['GET', 'POST'])
def login():
    """
    Crea el formulario login y redirige a la pagina, recibe las peticiones get y post,
    valida el nombre de usuario y contrasenha para mandarlo a la pagina principal de login
    """
    
    form = LoginForm(request.form)
    
    # Realizamos la validacion de los datos ingresados al formulario
    if form.validate_on_submit():
        user = Usuario.query.filter_by(nombre=form.nombre.data).first()
        if user != None:
            if user.estado == 'DESACTIVO':
                flash('El usuario se encuentra con estado Desactivado', 'error-message')
                return redirect(url_for('acceso.login'))
        
            else:
            
                # Utilizamos werzeug para realizar la validacion de usuario con su contrasenha
                if user and check_password_hash(user.contrasenha, form.contrasenha.data):
                    
                    #Redirigimos al usuario a la pagina de eleccion de proyectos
                    return redirect(url_for('acceso.elegir_proyecto', usuario =user.nombre, aux=0))
        
                flash('Nombre de usuario o contrasenha incorrecta', 'error-message')
        else:
            flash('El usuario no existe en el sistema', 'error-message')
    return render_template("acceso/login.html", form=form)



@mod.route('/usuario/', methods=['GET', 'POST'])
def ingresar_usuario():
    """
    Crea el formulario para ingresar el usuario al cual se le quiere
    establecer una nueva contrasenha y redirige a la pagina, recibe las peticiones get y post,
    valida los datos ingresados para mandarlo a la pagina principal de ingreso de usuario
    """
    
    form = IngresarUsuarioForm(request.form)
    
    # Realizamos la validacion de los datos ingresados al formulario
    if form.validate_on_submit():
        
        # Obtenemos el usuario con el nombre de usuario que se paso en el formulario
        user = Usuario.query.filter_by(nombre=form.nombre.data).first()
        
        if user != None :
            
            if user.estado == 'DESACTIVO':
                flash('El usuario se encuentra con estado Desactivado', 'error-message')
                return redirect(url_for('acceso.ingresar_usuario'))
            else:
                # Desplegamos un mensaje de bienvenida en pantalla
                # Desplegamos un mensaje de bienvenida en pantalla
                flash('Usuario %s , por favor responda la pregunta de seguridad e ingrese la nueva clave'
                  % user.nombre)
         
                # Cuando se apriete el boton Aceptar de la pagina, se redirige al metodo 
                # cambiar_contrasenha
                return redirect(url_for('acceso.cambiar_contrasenha', nombre=user.nombre))
        else:
            flash('El nombre de usuario no existe', 'error-message')
    
    return render_template("acceso/ingresar_usuario.html", form=form)


@mod.route('/contrasenha/<nombre>/', methods=['GET', 'POST'])
def cambiar_contrasenha(nombre):
    """
    Crea el formulario para responder la pregunta de seguridad del usuario
    e ingresar la nueva contrasenha, recibe las peticiones get y post,valida los datos ingresados
    para mandarlo a la pagina principal de ingreso de usuario
    @param nombre: nombre del usuario a quien se debe cambiar la contrasenha
    """
    
    # Obtenemos el usuario cuyo nombre de usuario fue proporcionado
    user = Usuario.query.filter_by(nombre=nombre).first()
    
    if user.estado == 'DESACTIVO':
        flash('El usuario se encuentra con estado Desactivado', 'error-message')
        return redirect(url_for('acceso.ingresar_usuario'))
    
    else:
        form = CambiarContrasenhaForm(request.form)
    
        # Realizamos la validacion de los datos ingresados al formulario
        if request.method == 'POST' and form.is_submitted() and form.validate():
        
            # Verificamos que la respuesta dada en el formulario sea la misma que el usuario tiene
            # almacenada en base de datos
            if user.respuesta == form.respuesta.data:
            
                # Establecemos la nueva contrasenha
                user.setContrasenha(generate_password_hash(form.contrasenha.data))
            
                # Add y comiteamos los cambios hechos al usuario
                db.session.add(user)
                db.session.commit()
            
                # Redirigimos al metodo login
                return redirect(url_for('acceso.login'))
        
            flash('Respuesta incorrecta', 'error-message')
    return render_template("acceso/cambiar_contrasenha.html", form=form, user=user)


@mod.route('/logout/')
def logout():
    session.pop('usuario_id', None)
    session.pop('proyecto_id', None)
    session.pop('proyecto_nombre', None)
    #flash('You were logged out')
    return redirect(url_for('acceso.login'))


@mod.route('/cambiar/', methods=['GET', 'POST'])
def cambiar_proyecto():
    """
    Metodo auxiliar que llama a elegir_proyecto, cuando el usuario desea ingresar a otro proyecto
    en el cual es miembro sin necesidad de cerrar sesion
    """
    
    return redirect(url_for('acceso.elegir_proyecto', usuario=g.user.nombre, aux=1))